package com.szsh.aiot.hsm.service.impl;

import com.google.gson.Gson;
import com.szsh.aiot.common.core.domain.AjaxResult;
import com.szsh.aiot.common.utils.TimeTools;
import com.szsh.aiot.hsm.dto.ehoHome.*;
import com.szsh.aiot.hsm.mapper.IEhomeCameraMapper;
import com.szsh.aiot.hsm.service.HousekeepingService;
import com.szsh.aiot.hsm.thirdService.EHomeClient;
import com.szsh.aiot.hsm.utils.Hash163;
import org.apache.commons.lang3.StringUtils;
import org.influxdb.impl.InfluxDBMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:看家卫生功能-摄像头
 * @Date 2023/10/24: 10:31
 * @Author: LOADING>>>>>
 */

@Service
public class HousekeepingServiceImpl implements HousekeepingService {

    public static final Logger LOGGER = LoggerFactory.getLogger(HousekeepingServiceImpl.class);

    private final Gson gson = new Gson();

    @Autowired
    private IEhomeCameraMapper ehomeCameraMapper;

    @Autowired
    private EHomeClient eHomeClient;

    @Autowired
    private Hash163 hash163;

    @Autowired
    private InfluxDBMapper influxMapper;

    @Override
    public AjaxResult getEhomeCameraAccessInfos(String broadbandNO) {

        List<EhomeCameraAccessModel> ehomeCameraAccessModels = new ArrayList<>();
        try {
            Date date = new Date();
            Date threeBeforDate = TimeTools.plusDays(new Date(), -3);
            String startDate = TimeTools.date2String(threeBeforDate, "yyyy-MM-dd HH:mm:ss");
            String endDate = TimeTools.date2String(date, "yyyy-MM-dd HH:mm:ss");
            IEhomeCamera iEhomeCamera = new IEhomeCamera();
            iEhomeCamera.setBroadbandNO(broadbandNO);

            List<IEhomeCamera> ehomeCameraList = ehomeCameraMapper
                    .selectIEhomeCameraList(iEhomeCamera);

            ehomeCameraList.forEach(ehomeCamera -> {
                EhomeCameraAccessModel cameraAccessModel = new EhomeCameraAccessModel();
                cameraAccessModel.setId(ehomeCamera.getId());
                cameraAccessModel.setDevicecode(ehomeCamera.getDevicecode());
                cameraAccessModel.setCameranickname(ehomeCamera.getCameranickname());

                LiveAndLookBack liveAndLookBack = eHomeClient
                        .getLiveAndLookBack(ehomeCamera.getDevicecode(), startDate, endDate, 1, 1);

                int count = 0;
                if (Objects.nonNull(liveAndLookBack)) {
                    count = liveAndLookBack.getTotalCount();
                }
                cameraAccessModel.setCount(count);
                ehomeCameraAccessModels.add(cameraAccessModel);
            });
        } catch (Exception e) {
            LOGGER.error("获取3天内摄像头访问提醒数据发生异常{}", broadbandNO, e);
            return AjaxResult.error("获取3天内摄像头访问提醒数据发生异常");
        }
        return AjaxResult.success(ehomeCameraAccessModels);
    }

    @Override
    public AjaxResult deleteEhomeCameraInfo(Long id) {
       int deleteResult = ehomeCameraMapper.deleteIEhomeCameraById(id);
       if (deleteResult == 0){
           return AjaxResult.error("删除失败");
       }
       return AjaxResult.success();
    }

    @Override
    public AjaxResult bindEhomePhone(String broadbandNO, String phone) {

        // 先调用接口查询是否存在天翼看家摄像头
        List<IEhomeCamera> cameraDataList = eHomeClient.getCameraPhoneInfo(phone);
        if (cameraDataList.isEmpty()){
            return AjaxResult.error("不存在天翼看家摄像头");
        }

        // 再查询库里是否已经存在绑定数据
        IEhomeCamera iEhomeCamera = new IEhomeCamera();
        iEhomeCamera.setBroadbandNO(broadbandNO);
        iEhomeCamera.setPhone(phone);
        List<IEhomeCamera> esitEhomeCameras = ehomeCameraMapper.selectIEhomeCameraList(iEhomeCamera);
        List<IEhomeCamera> ehomeCameraList = new ArrayList<>();
        cameraDataList.forEach(cameraData -> {
            IEhomeCamera ehomeCamera = new IEhomeCamera();
            ehomeCamera.setBroadbandNO(broadbandNO);
            ehomeCamera.setPhone(phone);
            ehomeCamera.setDevicecode(cameraData.getDevicecode());
            ehomeCamera.setCameranickname(cameraData.getCameranickname());
            ehomeCamera.setFactoryname(cameraData.getFactoryname());
            ehomeCamera.setModel(cameraData.getModel());
            ehomeCameraList.add(ehomeCamera);
        });

        // 二者取差集
        List<IEhomeCamera> newEhomeCameraList = ehomeCameraList.stream()
                .filter(item -> !esitEhomeCameras.stream().map(e -> e.getDevicecode())
                        .collect(Collectors.toList()).contains(item.getDevicecode()))
                .collect(Collectors.toList());
        if (!newEhomeCameraList.isEmpty()) {
            newEhomeCameraList.stream().forEach(t->ehomeCameraMapper.insertIEhomeCamera(t));
        }

        LOGGER.info("绑定天翼看家摄像头手机号,broadbandNO{},phone{},ehomeCameraList{}", broadbandNO, phone,
                gson.toJson(ehomeCameraList));
        return AjaxResult.success();
    }

    @Override
    public AjaxResult getCameraAccessInfos(String devicecode, int pageno, String broadbandNO) {

        CameraAccessInfo cameraAccessInfo = new CameraAccessInfo();
        List<AccessInfoDesc> accessInfoDescList = new ArrayList<>();
        try {
            Date date = new Date();
            Date threeBeforDate = TimeTools.plusDays(new Date(), -3);
            String startDate = TimeTools.date2String(threeBeforDate, "yyyy-MM-dd HH:mm:ss");
            String endDate = TimeTools.date2String(date, "yyyy-MM-dd HH:mm:ss");
            String timeDescStart = TimeTools.date2String(threeBeforDate, "yyyy.MM.dd");
            String timeDescEnd = TimeTools.date2String(date, "yyyy.MM.dd");
            String time = timeDescStart + "-" + timeDescEnd;
            cameraAccessInfo.setTime(time);
            LiveAndLookBack liveAndLookBack = eHomeClient.getLiveAndLookBack(devicecode, startDate,
                    endDate, pageno, 10);

            if (liveAndLookBack == null){
                return AjaxResult.success(cameraAccessInfo);
            }


            cameraAccessInfo.setCurrentpageno(pageno);
            cameraAccessInfo.setDevicecode(devicecode);
            cameraAccessInfo.setHasnextpage(liveAndLookBack.isHasNextPage());
            cameraAccessInfo.setNextpageno(liveAndLookBack.getNextPage());
            List<LiveAndLookBackItems> liveAndLookBackItems = liveAndLookBack
                    .getLiveAndLookBackItems();

            liveAndLookBackItems.forEach(liveAndLookBackItem -> {
                // 处理返回前端显示的数据格式
                dealAccessInfoDesc(liveAndLookBackItem, accessInfoDescList);
                try {
                    // 保存到influxdb中
                    insertIntoInfluxdb(broadbandNO, liveAndLookBackItem);
                } catch (Exception e) {
                    LOGGER.error("保存到influxdb数据出错");
                }
            });
            cameraAccessInfo.setAccessInfoDesc(accessInfoDescList);
        } catch (Exception e) {
            LOGGER.error("分页获取天翼看家摄像头访问记录发生异常broadbandNO[{}],devicecode[{}]", broadbandNO,
                    devicecode, e);
        }
        return AjaxResult.success(cameraAccessInfo);
    }


    /**
     * 处理页面展示数据格式
     *
     * @param liveAndLookBackItem
     * @param accessInfoDescList
     */
    private void dealAccessInfoDesc(LiveAndLookBackItems liveAndLookBackItem,
                                    List<AccessInfoDesc> accessInfoDescList) {
        String phone = liveAndLookBackItem.getPhone();
        int usertype = liveAndLookBackItem.getUserType();
        String dt = liveAndLookBackItem.getDt();
        int ct = liveAndLookBackItem.getCt();
        int ty = liveAndLookBackItem.getTy();
        String startdateStr = liveAndLookBackItem.getLvt();
        String enddateStr = liveAndLookBackItem.getElvt();
        String usertypedesc = "";
        if (usertype == 0) {
            usertypedesc = " (解绑号)";
        } else if (usertype == 1) {
            usertypedesc = " (绑定号)";
        } else if (usertype == 2) {
            usertypedesc = " (分享号)";
        } else if (usertype == 3) {
            usertypedesc = " (未知)";
        }
        String account = phone + usertypedesc;
        String ctdesc = "";
        if (ct == 1) {
            ctdesc = " (Android)";
        } else if (ty == 2) {
            ctdesc = " (iOS)";
        }
        String devicename = dt + ctdesc;
        String tydesc = "";
        if (ty == 1) {
            tydesc = "直播";
        } else if (ty == 2) {
            tydesc = "云回看";
        }
        Date startDate = TimeTools.string2Time(startdateStr);
        String newStartDateStr = TimeTools.date2String(startDate, "MM月dd日 HH:mm:ss");
        String newEndDateStr = "";
        if (!StringUtils.isEmpty(enddateStr)) {
            Date endDate = TimeTools.string2Time(enddateStr);
            newEndDateStr = "-" + TimeTools.date2String(endDate, "HH:mm:ss");
        }
        String time = newStartDateStr + newEndDateStr;

        AccessInfoDesc accessInfoDesc = new AccessInfoDesc();
        accessInfoDesc.setAccount(account);
        accessInfoDesc.setDevicename(devicename);
        accessInfoDesc.setType(tydesc);
        accessInfoDesc.setTime(time);
        accessInfoDescList.add(accessInfoDesc);
    }

    /**
     * 天翼看家卫士摄像头访问信息存入influxDB
     *
     * @param broadbandNO
     * @param liveAndLookBackItem
     */
    private void insertIntoInfluxdb(String broadbandNO, LiveAndLookBackItems liveAndLookBackItem) throws Exception {
        Optional<ECameraAccessInfo> push = makeData(broadbandNO, liveAndLookBackItem);
        push.ifPresent(data -> {
            influxMapper.save(data);
        });
    }

    /**
     * 数据转换为influxdb对象
     *
     * @param liveAndLookBackItem
     * @return
     */
    private Optional<ECameraAccessInfo> makeData(String broadbandNO,
                                                 LiveAndLookBackItems liveAndLookBackItem) throws Exception {
        if (Objects.isNull(liveAndLookBackItem)) {
            LOGGER.error("天翼看家摄像头访问信息有误，忽略broadbandNO{}", broadbandNO);
            return Optional.empty();
        }
        ECameraAccessInfo cameraAccessInfo = new ECameraAccessInfo();
        cameraAccessInfo.setDevicetype(liveAndLookBackItem.getDt());
        cameraAccessInfo.setClienttype(liveAndLookBackItem.getCt());
        cameraAccessInfo.setFirm(liveAndLookBackItem.getFirm());
        cameraAccessInfo.setType(liveAndLookBackItem.getTy());
        cameraAccessInfo.setHashPhone(hash163.sHash(liveAndLookBackItem.getPhone()));
        cameraAccessInfo.setPhone(liveAndLookBackItem.getPhone());
        cameraAccessInfo.setPlayid(liveAndLookBackItem.getLid());
        cameraAccessInfo.setVersion(liveAndLookBackItem.getV());
        cameraAccessInfo.setIp(liveAndLookBackItem.getIp());
        Date elvt = TimeTools.getDateTime(liveAndLookBackItem.getElvt(), "yyyy-MM-dd HH:mm:ss");
        cameraAccessInfo.setEndtime(elvt);
        Date lvt = TimeTools.getDateTime(liveAndLookBackItem.getLvt(), "yyyy-MM-dd HH:mm:ss");
        cameraAccessInfo.setStarttime(lvt);
        cameraAccessInfo.setUserType(liveAndLookBackItem.getUserType());
        cameraAccessInfo.setDevicecode(liveAndLookBackItem.getDc());
        return Optional.ofNullable(cameraAccessInfo);
    }

}
